package org.dromara.tearoom.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.resource.api.RemoteFileService;
import org.dromara.tearoom.domain.TerLockSerialnum;
import org.dromara.tearoom.domain.TerRoomDetails;
import org.dromara.tearoom.domain.bo.TerLockSerialnumBo;
import org.dromara.tearoom.domain.bo.TerOrderTimeBo;
import org.dromara.tearoom.domain.bo.TerRoomDetailsBo;
import org.dromara.tearoom.domain.bo.TerRoomDetailsWxBo;
import org.dromara.tearoom.domain.enums.RoomStatusEnum;
import org.dromara.tearoom.domain.vo.TerOrderVo;
import org.dromara.tearoom.domain.vo.TerRoomDetailsVo;
import org.dromara.tearoom.mapper.TerLockSerialnumMapper;
import org.dromara.tearoom.mapper.TerRegionalInfoMapper;
import org.dromara.tearoom.mapper.TerRoomDetailsMapper;
import org.dromara.tearoom.service.ITerOrderService;
import org.dromara.tearoom.service.ITerRoomDetailsService;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.List;

/**
 * 茶室详情Service业务层处理
 *
 * @author xch
 * @date 2025-03-26
 */
@RequiredArgsConstructor
@Service
public class TerRoomDetailsServiceImpl implements ITerRoomDetailsService {

    private final TerRoomDetailsMapper baseMapper;
    private final TerRegionalInfoMapper baseMapperregion;
    private final TerLockSerialnumMapper baseMapperserial;
    private final RemoteFileService remoteFileService;
    private final ITerOrderService orderService;
    /**
     * 查询茶室详情
     *
     * @param id 主键
     * @return 茶室详情
     */
    @Override
    public TerRoomDetailsVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 分页查询茶室详情列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 茶室详情分页列表
     */
    @Override
    public TableDataInfo<TerRoomDetailsVo> queryPageList(TerRoomDetailsBo bo, PageQuery pageQuery) {
        Page<TerRoomDetails> page = pageQuery.build();
        Page<TerRoomDetailsVo> result = baseMapper.selectVoPageList(page, bo);
        result.getRecords().stream().forEach(item->{
            TerOrderTimeBo timeBo=new TerOrderTimeBo();
            timeBo.setTearoomId(item.getId());
            if(ObjectUtil.isNotEmpty(bo.getStartTime())){
                timeBo.setStartDate(LocalDateTimeUtil.parseDate(bo.getStartTime(),"yyyy-MM-dd HH:mm"));
            }
            item.setTimeSlot(orderService.queryTimelist(timeBo));
            if(ObjectUtil.isNotEmpty(item.getTeroomImgurl())){
                item.setTeroomImgurl(remoteFileService.selectUrlByIds(item.getTeroomImgurl()));
            }
            if(RoomStatusEnum.isUsed(item.getStatus())){
                TerOrderVo terOrderVo=orderService.queryRecentBookTime(item.getId());
                if(ObjectUtil.isNotEmpty(terOrderVo)){
                    item.setRecentBookStartTime(terOrderVo.getStartTime());
                    item.setRecentBookEndTime(terOrderVo.getEndTime());
                }
            }else{
                Boolean isUsed=orderService.checkTearoomAvailability(item.getId(),bo.getStartTime(),bo.getEndTime());
                if(isUsed){
                    item.setStatus(RoomStatusEnum.USED.getType());
                }
            }
        });
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的茶室详情列表
     *
     * @param bo 查询条件
     * @return 茶室详情列表
     */
    @Override
    public List<TerRoomDetailsVo> queryList(TerRoomDetailsBo bo) {
        LambdaQueryWrapper<TerRoomDetails> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    @Override
    public List<TerRoomDetailsVo> queryList(TerRoomDetailsWxBo bo) {
        LambdaQueryWrapper<TerRoomDetails> lqw = buildQuerywxWrapper(bo);
        List<TerRoomDetailsVo> resultList=baseMapper.selectVoList(lqw);
        resultList.stream().forEach(item->{
            if(ObjectUtil.isNotEmpty(item.getTeroomImgurl())){
                item.setTeroomImgurl(remoteFileService.selectUrlByIds(item.getTeroomImgurl()));
            }
            if(ObjectUtil.isNotEmpty(item.getCarouselImages())){
                item.setCarouselImages(remoteFileService.selectUrlByIds(item.getCarouselImages()));
            }
        });
        return resultList;
    }

    private LambdaQueryWrapper<TerRoomDetails> buildQueryWrapper(TerRoomDetailsBo bo) {

        LambdaQueryWrapper<TerRoomDetails> lqw = Wrappers.lambdaQuery();
        lqw.orderByAsc(TerRoomDetails::getOrderNum);
        lqw.like(StringUtils.isNotBlank(bo.getTeroomName()), TerRoomDetails::getTeroomName, bo.getTeroomName());
        lqw.like(ObjectUtil.isNotEmpty(bo.getGroupId()), TerRoomDetails::getGroupId, bo.getGroupId());
        lqw.eq(ObjectUtil.isNotEmpty(bo.getStatus()), TerRoomDetails::getStatus, bo.getStatus());
        return lqw;
    }

    private LambdaQueryWrapper<TerRoomDetails> buildQuerywxWrapper(TerRoomDetailsWxBo bo) {
        LambdaQueryWrapper<TerRoomDetails> lqw = Wrappers.lambdaQuery();
        lqw.eq(ObjectUtil.isNotEmpty(bo.getGroupId()),TerRoomDetails::getGroupId, bo.getGroupId());
        lqw.eq(ObjectUtil.isNotEmpty(bo.getId()),TerRoomDetails::getId, bo.getId());
        lqw.orderByAsc(TerRoomDetails::getOrderNum);
        return lqw;
    }

    /**
     * 新增茶室详情
     *
     * @param bo 茶室详情
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(TerRoomDetailsBo bo) {
        bo.setDelFlag("0");
        //新增茶室详情信息
        TerRoomDetails add = BeanUtil.toBean(bo, TerRoomDetails.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        //新增配置序号关联信息
        TerLockSerialnumBo bos= new TerLockSerialnumBo();
        bos.setTeroomId(bo.getId());
        bos.setTeroomName(bo.getTeroomName());
        bos.setDelFlag("0");
        TerLockSerialnum addS =BeanUtil.toBean(bos, TerLockSerialnum.class);
        baseMapperserial.insert(addS);
        return flag;
    }

    /**
     * 修改茶室详情
     *
     * @param bo 茶室详情
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(TerRoomDetailsBo bo) {
        TerRoomDetails update = MapstructUtils.convert(bo, TerRoomDetails.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(TerRoomDetails entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 校验并批量删除茶室详情信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            // 检查所有记录是否都处于已删除状态
            List<TerRoomDetailsVo> records = baseMapper.selectVoList(new LambdaQueryWrapper<TerRoomDetails>()
                    .select(TerRoomDetails::getId, TerRoomDetails::getDelFlag)
                    .in(TerRoomDetails::getId, ids));
            if (records.size() != ids.size()) {
                throw new ServiceException("部分记录不存在或已被删除");
            }
        }
        return baseMapper.deleteByIds(ids) > 0;
    }

    /**
     * 校验并批量恢复茶室详情信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean recoverWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (ids == null || ids.isEmpty()) {
            throw new ServiceException("恢复ID不能为空");
        }
        // 有效性校验
        if (Boolean.TRUE.equals(isValid)) {
            List<TerRoomDetails> records = baseMapper.selectDelFlagsByIds(ids);
            // 检查记录数是否匹配
            if (records.size() != ids.size()) {
                throw new ServiceException("部分记录不存在或已被删除");
            }
            // 检查是否全部为已删除状态
            boolean hasNotDeleted = records.stream()
                    .anyMatch(item -> !"1".equals(item.getDelFlag()));
            if (hasNotDeleted) {
                throw new ServiceException("存在非删除状态记录，无法恢复");
            }
        }
        // 执行恢复操作
        int updateCount = baseMapper.recoverByIds(ids, LoginHelper.getUserId());
        if (updateCount == 0) {
            throw new ServiceException("恢复失败，请检查记录状态");
        }
        return updateCount>0;
    }

    /**
     * 校验并批量永久茶室详情信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean foreverDeleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (ids == null || ids.isEmpty()) {
            throw new ServiceException("恢复ID不能为空");
        }
        // 有效性校验
        if (Boolean.TRUE.equals(isValid)) {
            List<TerRoomDetails> records = baseMapper.selectDelFlagsByIds(ids);
            // 检查记录数是否匹配
            if (records.size() != ids.size()) {
                throw new ServiceException("部分记录不存在或已被删除");
            }
            // 检查是否全部为已删除状态
            boolean hasNotDeleted = records.stream()
                    .anyMatch(item -> !"1".equals(item.getDelFlag()));
            if (hasNotDeleted) {
                throw new ServiceException("存在非删除状态记录，无法永久删除");
            }
        }
        // 执行恢复操作
        int deleteCount = baseMapper.foreverDeleteByIds(ids);
        if (deleteCount == 0) {
            throw new ServiceException("永久删除失败，请检查记录状态");
        }
        return deleteCount>0;
    }

    /**
     * 查询符合条件的茶室详情列表
     *
     * @param groupIds 查询条件
     * @return 茶室详情列表
     */
    @Override
    public List<TerRoomDetailsVo> queryListByGroupIds(Collection<Long> groupIds) {
        List<TerRoomDetailsVo> list= baseMapper.selectVoList(new LambdaQueryWrapper<TerRoomDetails>().in(TerRoomDetails::getGroupId, groupIds));
        list.stream().forEach(item->{
            if(ObjectUtil.isNotEmpty(item.getTeroomImgurl())){
                item.setTeroomImgurl(remoteFileService.selectUrlByIds(item.getTeroomImgurl()));
            }
            if(ObjectUtil.isNotEmpty(item.getCarouselImages())){
                item.setCarouselImages(remoteFileService.selectUrlByIds(item.getCarouselImages()));
            }
        });
        return list;
    }

    @Override
    public int queryTotal() {
        return baseMapper.selectTotal();
    }

}
